package com.ngrok.handler;

import com.alibaba.fastjson.JSONObject;
import com.ngrok.BytesUtil;
import com.ngrok.NgrokContext;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
        * Created by pj on 2017/9/28.
        */

public class SocketHandler  extends SimpleChannelInboundHandler<byte[]> {


    private NgrokContext context;

    private AtomicInteger atomicInteger=new AtomicInteger();

    public SocketHandler(NgrokContext context){
        this.context=context;
    }
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, byte[] bytes) throws Exception {
        String json=new String(bytes);
        System.out.println(json);
        JSONObject jsonObject=JSONObject.parseObject(json);
        Map<String,Object> payload= (Map<String, Object>) jsonObject.get("Payload");
        String clientid=(String)payload.get("ClientId");
        String type=(String)jsonObject.get("Type");
        if(type!=null){
            switch (type){
                case "StartProxy" :
                     System.out.println("成功启动映射");
//                    String StartProxy="{\"Type\": \"RegProxy\", \"Payload\": {\"ClientId\": \"" + context.getClientid("127.0.0.1") + "\"}}";
//                    byte[] lenbufa = BytesUtil.longToBytes(StartProxy.length(), 0);
//                    byte[] xxa = StartProxy.getBytes();
//                    byte[] msgpacka = BytesUtil.addBytesnew(StartProxy.length() + 8, lenbufa, xxa);
//                    context.getNewChannel("server.ngrok.cc",4443).writeAndFlush(Unpooled.copiedBuffer(msgpacka));
                    break;
                case  "AuthResp" :
                    String aa="{\"Type\": \"ReqTunnel\", \"Payload\": {\"RemotePort\": 0, \"HttpAuth\": \"\", \"Protocol\": \"http\", \"Hostname\": \"\", \"ReqId\": \""+context.getChars()+"\", \"Subdomain\": \""+context.getConfig().getApi().getData().get(0).getSubdomain()+"\"}}";
                    byte[] lenbuf1 = BytesUtil.longToBytes(aa.length(), 0);
                    byte[] xx1 = aa.getBytes();
                    byte[] msgpack1 = BytesUtil.addBytesnew(aa.length() + 8, lenbuf1, xx1);
                    channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer(msgpack1));
                    new Thread(()->{ //模拟心跳
                        while (true){
                            try {
                                Thread.sleep(3000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            String kk="{\"Type\": \"Ping\", \"Payload\": {}}";
                            byte[] qwe = BytesUtil.longToBytes(kk.length(), 0);
                            byte[] ee = kk.getBytes();
                            byte[] as = BytesUtil.addBytesnew(kk.length() + 8, qwe, ee);
                            channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer(as)).addListener(future -> {
                                    if(!future.isSuccess()){
                                        int count=atomicInteger.getAndIncrement();
                                        System.out.println("++");
                                        if(count!=0&&count%8==0){
                                            channelHandlerContext.channel().disconnect().addListener(future1 -> {
//                                                if(future.isSuccess()){
                                                System.out.println("发送失败进行重新连接操作");
                                                context.init();
//                                                }
                                            });
                                        }
                                    }
                            });
                        }
                    }).start();
                    break;

                case  "NewTunnel" :
                    String NewTunnel="{\"Type\": \"RegProxy\", \"Payload\": {\"ClientId\": \"" + context.getClientid(context.getConfig().getApi().getData().get(0).getProto().getHttp()) + "\"}}";
                    byte[] lenbuf = BytesUtil.longToBytes(NewTunnel.length(), 0);
                    byte[] xx = NewTunnel.getBytes();
                    byte[] msgpack = BytesUtil.addBytesnew(NewTunnel.length() + 8, lenbuf, xx);
                    Channel channel=context.getNewChannel(context.getConfig().getApi().getServer(),context.getConfig().getApi().getProt());
                    channel.writeAndFlush(Unpooled.copiedBuffer(msgpack));
                    break;
                case "ReqProxy" :
//                    String kk="{\"Type\": \"Ping\", \"Payload\": {}}";
//                    byte[] qwe = BytesUtil.longToBytes(kk.length(), 0);
//                    byte[] ee = kk.getBytes();
//                    byte[] as = BytesUtil.addBytesnew(kk.length() + 8, qwe, ee);
//                    channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer(as));
                    String StartProxy="{\"Type\": \"RegProxy\", \"Payload\": {\"ClientId\": \"" + context.getClientid(context.getConfig().getApi().getData().get(0).getProto().getHttp()) + "\"}}";
                    byte[] lenbufa = BytesUtil.longToBytes(StartProxy.length(), 0);
                    byte[] xxa = StartProxy.getBytes();
                    byte[] msgpacka = BytesUtil.addBytesnew(StartProxy.length() + 8, lenbufa, xxa);
                    new Thread(()->{ //使用当前线程方式发生死锁现象
                        context.getNewChannel(context.getConfig().getApi().getServer(),context.getConfig().getApi().getProt()).writeAndFlush(Unpooled.copiedBuffer(msgpacka));
                    }).start();
                    break;
                case "RegProxy":
                        System.out.println("------------");
                    break;
            }
        }
        System.out.println(type);
        if(clientid!=null){
            context.addClientId(context.getConfig().getApi().getData().get(0).getProto().getHttp(),clientid);
        }
    }
}
